//package com.ramble.gatewayservice.filter;
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.ObjectProvider;
//import org.springframework.cloud.client.ServiceInstance;
//import org.springframework.cloud.client.loadbalancer.DefaultResponse;
//import org.springframework.cloud.client.loadbalancer.EmptyResponse;
//import org.springframework.cloud.client.loadbalancer.Request;
//import org.springframework.cloud.client.loadbalancer.Response;
//import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
//import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
//import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
//import org.springframework.http.HttpHeaders;
//import org.springframework.util.ObjectUtils;
//import reactor.core.publisher.Flux;
//import reactor.core.publisher.Mono;
//
//import java.util.*;
//
///**
// * @Project ramble-spring-cloud
// * @Package com.ramble.gatewayservice.filter
// * @Class GrayLoadBalancerFilter
// * @Date 2022/2/17 14:30
// * @Author MingliangChen
// * @Email chen.mingliang@nghinsights.com
// * @Description
// */
//
//@Slf4j
//public class GrayLoadBalancerFilter implements ReactorServiceInstanceLoadBalancer {
//
//    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
//    private String serviceId;
//
//    public GrayLoadBalancerFilter(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
//        this.serviceId = serviceId;
//        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
//    }
//
//    @Override
//    public Mono<Response<ServiceInstance>> choose(Request request) {
//        HttpHeaders headers = (HttpHeaders) request.getContext();
//        if (this.serviceInstanceListSupplierProvider != null) {
//            ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier) this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
//            return ((Flux) supplier.get()).next().map(list -> getInstanceResponse((List<ServiceInstance>) list, headers));
//        }
//        return null;
//    }
//
//
//    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances, HttpHeaders headers) {
//        if (instances.isEmpty()) {
//            return getServiceInstanceEmptyResponse();
//        } else {
//            return getServiceInstanceResponseWithWeight(instances);
//        }
//    }
//
//    /**
//     * 根据版本进行分发
//     *
//     * @param instances
//     * @param headers
//     * @return
//     */
//    private Response<ServiceInstance> getServiceInstanceResponseByVersion(List<ServiceInstance> instances, HttpHeaders headers) {
//        String versionNo = headers.getFirst("version");
//        System.out.println(versionNo);
//        Map<String, String> versionMap = new HashMap<>();
//        versionMap.put("version", versionNo);
//        final Set<Map.Entry<String, String>> attributes =
//                Collections.unmodifiableSet(versionMap.entrySet());
//        ServiceInstance serviceInstance = null;
//        for (ServiceInstance instance : instances) {
//            Map<String, String> metadata = instance.getMetadata();
//            if (metadata.entrySet().containsAll(attributes)) {
//                serviceInstance = instance;
//                break;
//            }
//        }
//
//        if (ObjectUtils.isEmpty(serviceInstance)) {
//            return getServiceInstanceEmptyResponse();
//        }
//        return new DefaultResponse(serviceInstance);
//    }
//
//    /**
//     * 根据在nacos中配置的权重值，进行分发
//     *
//     * @param instances
//     * @return
//     */
//    private Response<ServiceInstance> getServiceInstanceResponseWithWeight(List<ServiceInstance> instances) {
//        Map<ServiceInstance, Integer> weightMap = new HashMap<>();
//        for (ServiceInstance instance : instances) {
//            Map<String, String> metadata = instance.getMetadata();
//            System.out.println(metadata.get("version") + "-->weight:" + metadata.get("weight"));
//            log.info(metadata.get("version") + "-->weight:" + metadata.get("weight"));
//            if (metadata.containsKey("weight")) {
//                weightMap.put(instance, Integer.valueOf(metadata.get("weight")));
//            }
//        }
//        WeightMeta<ServiceInstance> weightMeta = WeightRandomUtils.buildWeightMeta(weightMap);
//        if (ObjectUtils.isEmpty(weightMeta)) {
//            return getServiceInstanceEmptyResponse();
//        }
//        ServiceInstance serviceInstance = weightMeta.random();
//        if (ObjectUtils.isEmpty(serviceInstance)) {
//            return getServiceInstanceEmptyResponse();
//        }
//        System.out.println(serviceInstance.getMetadata().get("version"));
//        log.info(serviceInstance.getMetadata().get("version"));
//        return new DefaultResponse(serviceInstance);
//    }
//
//    private Response<ServiceInstance> getServiceInstanceEmptyResponse() {
//        log.warn("No servers available for service: " + this.serviceId);
//        return new EmptyResponse();
//    }
//}
